package com.markerhub.service.impl;

import com.alibaba.fastjson.JSON;
import com.markerhub.common.lang.Result;
import com.markerhub.entity.Blog;
import com.markerhub.entity.ElasticSearchBlog;
import com.markerhub.mapper.BlogMapper;
import com.markerhub.service.BlogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 关注公众号：MarkerHub
 * @since 2022-03-23
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements BlogService {

    @Autowired
    private BlogMapper blogMapper;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    public String ElasticSearchUpdate()throws IOException {
        List<Blog> blogs=blogMapper.blogAll();
        ElasticSearchBlog esb=new ElasticSearchBlog();
        IndexRequest request=new IndexRequest("vueblog");

        for(Blog blog:blogs){
            request.id(String.valueOf(blog.getId()));
            esb.setId(blog.getId());
            esb.setContent(blog.getContent());
            esb.setCreated(blog.getCreated());
            esb.setDescription(blog.getDescription());
            esb.setStatus(blog.getStatus());
            esb.setTitle(blog.getTitle());
            esb.setUserId(blog.getUserId());
            request.source(JSON.toJSONString(esb), XContentType.JSON);
            restHighLevelClient.index(request, RequestOptions.DEFAULT);
        }

        return "执行成功!";
    }

    public Result Search(String keyword,int pageNum,int pageSize)throws Exception{
        pageNum=pageNum<=0?1:pageNum;
        pageSize=pageSize<=0?1:pageSize;

        SearchRequest request=new SearchRequest("vueblog");
        SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();
        sourceBuilder.from(pageNum);
        sourceBuilder.size(pageSize);
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title",keyword);
        sourceBuilder.query(matchQueryBuilder);

        HighlightBuilder highlightBuilder=new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.requireFieldMatch(false);
        highlightBuilder.preTags("<span style='color: red'>");
        highlightBuilder.postTags("</span>");
        sourceBuilder.highlighter(highlightBuilder);

        request.source(sourceBuilder);
        SearchResponse response=restHighLevelClient.search(request,RequestOptions.DEFAULT);

        ArrayList<Map<String,Object>> list=new ArrayList<>();
        SearchHit[] searchHit=response.getHits().getHits();
        //TotalHits total=response.getHits().getTotalHits();
        //long totalsValue=total.value;
        for(SearchHit hits:searchHit){
            Map<String, HighlightField> highlightFields=hits.getHighlightFields();
            HighlightField productNames= highlightFields.get("title");
            Map<String,Object> sourceAsMap=hits.getSourceAsMap();
            if(productNames!=null){
                Text[] fragments=productNames.fragments();
                String title="";
                for(Text text:fragments){
                    title+=text;
                }
                sourceAsMap.put("title",title);
                //sourceAsMap.put("total",totalsValue);

            }
                list.add(sourceAsMap);
        }
        return Result.succ(list);
    }

}
